﻿using Redis;
using Redis.Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RedisTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            radioString.Checked = true;
            radioInsert.Checked = true;
        }

        int structType = 0;//数据结构 0字符串 1hash 2List 3Set 4Sorted
        int optType = 0;//操作类型 0单条插入 1单条查询 2批量插入 3批量查询



        /// <summary>
        /// 开始测试
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Test_Click(object sender, EventArgs e)
        {
            try
            {
                //数据结构
                if (radioString.Checked)
                    structType = 0;
                else if (radioHash.Checked)
                    structType = 1;
                else if (radioList.Checked)
                    structType = 2;
                else if (radioSet.Checked)
                    structType = 3;
                else
                    structType = 4;

                //操作类型
                if (radioInsert.Checked)
                    optType = 0;
                else if (radioSearch.Checked)
                    optType = 1;
                else if (radioInserts.Checked)
                    optType = 2;
                else
                    optType = 3;

                bool openThread = chk_OpenThread.Checked;//是否开启多线程
                int threadNum = Convert.ToInt32(txt_ThreadNum.Text); //线程个数
                int cycleIndex = Convert.ToInt32(txt_cycleIndex.Text);//循环次数
                int cycleInterval = Convert.ToInt32(txt_cycleInterval.Text);//循环间隔

                Task.Run(() =>
                {
                    RedisOperation(structType, optType, openThread, threadNum, cycleIndex, cycleInterval);
                });

            }
            catch (Exception ex)
            {
                txt_result.Text = "填写参数错误：" + ex.ToString();
            }
        }

        /// <summary>
        /// Redis测试
        /// </summary>
        /// <param name="structType"></param>
        /// <param name="optType"></param>
        /// <param name="openThread"></param>
        /// <param name="threadNum"></param>
        /// <param name="cycleIndex"></param>
        /// <param name="cycleInterval"></param>
        private void RedisOperation(int structType, int optType, bool openThread, int threadNum, int cycleIndex, int cycleInterval)
        {
            long allTime = 0;
            int index = 0;
            if (openThread)
            {
                for (int count = 0; count < cycleIndex; count++)
                {
                    Thread writeThread = new Thread(new ParameterizedThreadStart((para) =>
                    {
                        Stopwatch sw = new Stopwatch();
                        for (int i = 0; i < threadNum; i++)
                        {
                            sw.Restart();
                            string result = DistinctionOperation(structType, optType);
                            sw.Stop();
                            allTime += sw.ElapsedMilliseconds;
                            result += "\r\n index:" + index++;
                            result += string.Format("\r\n线程{0}当前请求结束，用时{1}毫秒,平均耗时{2}", para, sw.ElapsedMilliseconds, allTime / index);
                            Thread.Sleep(cycleInterval);
                            if (!string.IsNullOrWhiteSpace(result))
                            {
                                BeginInvoke(new Action(() =>
                                {
                                    txt_result.AppendText(result + "...\r\n");
                                }));
                            }
                            else
                            {
                                BeginInvoke(new Action(() =>
                                {
                                    txt_result.AppendText("操作出错");
                                }));
                            }
                        }
                    }));
                    writeThread.IsBackground = true;
                    writeThread.Start(count);
                }
            }
            else
            {
                Stopwatch sw = new Stopwatch();
                string result = string.Empty;
                sw.Restart();
                DistinctionOperation(structType, optType);
                sw.Stop();
                allTime += sw.ElapsedMilliseconds;
                index++;
                result += string.Format("\r\n用时{0}毫秒,平均耗时{1}", sw.ElapsedMilliseconds, allTime / index);
                BeginInvoke(new Action(() =>
                {
                    txt_result.AppendText(result);
                }));
            }
        }

        /// <summary>
        /// 区别操作
        /// </summary>
        /// <param name="structType">数据结构 0字符串 1hash 2List 3Set 4Sorted</param>
        /// <param name="optType">操作类型 0单条插入 1单条查询 2批量插入 3批量查询</param>
        private string DistinctionOperation(int structType, int optType)
        {
            string result = string.Empty;
            switch (structType)
            {
                case 0:
                    result= StringOpt(optType);
                    break;
                case 1:
                    result= HashOpt(optType);
                    break;
                case 2:
                    result= ListOpt(optType);
                    break;
                case 3:
                    result=SetOpt(optType);
                    break;
                case 4:
                    result= SortedSetOpt(optType);
                    break;
            }
            return result;
        }

        /// <summary>
        /// 字符串操作
        /// </summary>
        /// <param name="optType">操作类型 0单条插入 1单条查询 2批量插入 3批量查询</param>
        private string StringOpt(int optType)
        {
            string result = string.Empty;
            int Nums = int.Parse(txtNums.Text);
            List<DemoModel> demoModel = new List<DemoModel>();
            List<string> demoModelkey = new List<string>();
            for (int i = 0; i < Nums; i++)
            {
                var testModel = new DemoModel()
                {
                    ID = Guid.NewGuid().ToString("N"),
                    Age = 12,
                    Name = "Kitty1",
                    Created = DateTime.Now
                };
                demoModel.Add(testModel);
                demoModelkey.Add(testModel.ID);
            }
            switch (optType)
            {
                case 0:
                    result = RedisHelper.GetRedisOperation(0).StringSet("StringOpt", "字符串操作").ToString();
                    break;
                case 1:
                    result = RedisHelper.GetRedisOperation(0).StringGet("StringOpt");
                    break;
                case 2:
                    result = RedisHelper.GetRedisOperation(0).StringSets(demoModelkey, demoModel).ToString();
                    break;
                case 3:
                    result = RedisHelper.GetRedisOperation(0).StringGetValues(demoModelkey).Count.ToString();
                    break;
            }
            return result;
        }

        /// <summary>
        /// hash操作
        /// </summary>
        /// <param name="optType">操作类型 0单条插入 1单条查询 2批量插入 3批量查询</param>
        private string HashOpt(int optType)
        {
            string result = string.Empty;
            int Nums = int.Parse(txtNums.Text);
            List<DemoModel> demoModel = new List<DemoModel>();
            List<string> demoModelkey = new List<string>();
            for (int i = 0; i < Nums; i++)
            {
                var testModel = new DemoModel()
                {
                    ID = Guid.NewGuid().ToString("N"),
                    Age = 12,
                    Name = "Kitty1",
                    Created = DateTime.Now
                };
                demoModel.Add(testModel);
                demoModelkey.Add(testModel.ID);
            }
            switch (optType)
            {
                case 0:
                    result = RedisHelper.GetRedisOperation(1).HashSet<DemoModel>("Kitty", demoModel[0].ID, demoModel[0]).ToString();
                    break;
                case 1:
                    RedisHelper.GetRedisOperation(1).HashGet<DemoModel>("Kitty", demoModel[0].ID);
                    break;
                case 2:
                    result = RedisHelper.GetRedisOperation(1).HashSets<DemoModel>("Kitty", demoModelkey,demoModel).ToString();
                    break;
                case 3:
                    RedisHelper.GetRedisOperation(1).HashGetAll<DemoModel>("Kitty");
                    break;
            }
            return result;
        }

        /// <summary>
        /// List操作
        /// </summary>
        /// <param name="optType"></param>
        private string ListOpt(int optType)
        {
            string result = string.Empty;
            switch (optType)
            {
                case 0:

                    break;
                case 1:

                    break;
                case 2:

                    break;
                case 3:

                    break;
            }

            return result;
        }

        /// <summary>
        /// Set操作
        /// </summary>
        /// <param name="optType"></param>
        private string SetOpt(int optType)
        {
            string result = string.Empty;
            switch (optType)
            {
                case 0:

                    break;
                case 1:

                    break;
                case 2:

                    break;
                case 3:

                    break;
            }

            return result;
        }

        /// <summary>
        /// SortedSet操作
        /// </summary>
        /// <param name="optType"></param>
        private string SortedSetOpt(int optType)
        {
            string result = string.Empty;
            switch (optType)
            {
                case 0:

                    break;
                case 1:

                    break;
                case 2:

                    break;
                case 3:

                    break;
            }

            return result;
        }
    }
}
